"""
Case Type   : 资源池化单集群-推进oldest_xmin
Case Name   : 修改ss_txnstatus_cache_size,单集群switchover;
Create At   : 2024/4/24
Owner       : zhengxue
Description :
    1、查询ss_txnstatus_cache_size默认值,show ss_txnstatus_cache_size;
    2、修改ss_txnstatus_cache_size为262144,gs_guc set -D {cluster/dn1} -c "ss_txnstatus_cache_size=262144"，重启集群;
    3、运行tpcc业务,主机配置文件primary_write.pg;
    4、集群间switchover;
    5、查询集群状态;
    6、在新主上运行tpcc业务,新主机配置文件standby1_write.pg;
    7、tpcc业务结束;查询集群状态;
    8、修改ss_txnstatus_cache_size为默认值,gs_guc set -D {cluster/dn1} -c "ss_txnstatus_cache_size=131072"，重启集群;
Expect      :
    1、显示默认值
    2、参数修改成功;
    3、tpcc运行正常;
    4、switchover成功;
    5、集群状态正常;
    6、在新主上tpcc运行正常;
    7、集群状态正常;
    8、恢复默认值成功;
History     :
"""

import os
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.ComThread import ComThread

Primary_SH = CommonSH('PrimaryDbUser')
Primary_ROOTSH = CommonSH('PrimaryRoot')

class SharedStorage(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.com = Common()
        self.constant = Constant()
        self.primaryRoot = Node('PrimaryRoot')

        self.logger.info("===Opengauss_Function_Guc_ForwardOldestXmin_Case0005开始执行===")
        status =  Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)

        self.assertTrue("Degraded" in status or "Normal" in status)

        self.txnstatus_cache_size_default = 131072
        self.txnstatus_cache_size_set = 262144
        self.txnstatus_cache_size = 'ss_txnstatus_cache_size'

    def test_forward_oldest_xmin(self):
        step1 = '======step1:查询ss_txnstatus_cache_size,默认值为131072;expect:查询成功======'
        self.logger.info(step1)
        status = Primary_ROOTSH.exec_cmd_under_root("rm -rf /data/benchmarksql-5.0/run/standby1_write.log")
        self.logger.info(status)
        status = Primary_ROOTSH.exec_cmd_under_root("rm -rf /data/benchmarksql-5.0/run/primary_write.log")
        self.logger.info(status)

        show_ss_txnstatus_cache_size = Primary_SH.execut_db_sql('''show ss_txnstatus_cache_size;''')
        self.logger.info(show_ss_txnstatus_cache_size)
        if '131072' in show_ss_txnstatus_cache_size:
            self.assertEqual("131072", show_ss_txnstatus_cache_size.split("\n")[-2].strip())
        else:
            result1 = Primary_SH.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.txnstatus_cache_size}={self.txnstatus_cache_size_default}')
            restart_res = Primary_SH.restart_db_cluster()
            show_txnstatus_cache_size = self.com.show_param(self.txnstatus_cache_size)
            self.assertEquals(show_txnstatus_cache_size, '131072', 'txnstatus_cache_size恢复默认值执行失败')

        step2 = '======step2:设置ss_txnstatus_cache_size为最大值;expect:设置成功======'
        self.logger.info(step2)
        result1 = Primary_SH.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.txnstatus_cache_size}={self.txnstatus_cache_size_set}')
        restart_res = Primary_SH.restart_db_cluster()
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        show_ss_txnstatus_cache_size = Primary_SH.execut_db_sql('''show ss_txnstatus_cache_size;''')
        self.logger.info(show_ss_txnstatus_cache_size)
        self.assertEqual("262144", show_ss_txnstatus_cache_size.split("\n")[-2].strip())

        step3 = '======step3:运行tpcc业务;expect:tpcc进程运行======'
        self.logger.info(step3)
        primary_tpcc = ComThread(self.com.start_tpcc,
                                 args=(self.primaryRoot,'/data/benchmarksql-5.0/run',
                                       './runBenchmark.sh primary_write.pg >> primary_write.log'))
        primary_tpcc.setDaemon(True)
        primary_tpcc.start()
        status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/primary_write.log")
        self.assertNotIn('socket is not closed', status, '主节点127断开TPCC连接')

        step4 = "======step4:集群间switchover;expect:switchover成功======"
        self.logger.info(step4)
        switch = Primary_SH.exec_cm_ctl(mode='switchover',
                                           param='-n 2',
                                           path=f'-D {macro.DB_INSTANCE_PATH}')
        self.logger.info(switch)
        self.assertIn(self.constant.cm_switchover_success_msg, switch,
                      '执行失败' + step4)
        time.sleep(20)

        step5 = "======step5:查看切换后的集群状态;expect:集群状态正常======"
        self.logger.info(step5)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + step5)
        self.assertIn('S Primary Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + step5)
        self.assertIn('P Standby Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + step5)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[2].split('6003')[-1],
                      '执行失败' + step5)

        step6 = '======step6:在新主上运行tpcc业务;expect:tpcc进程运行======'
        self.logger.info(step6)
        standby1_tpcc = ComThread(self.com.start_tpcc,
                                 args=(self.primaryRoot,'/data/benchmarksql-5.0/run',
                                       './runBenchmark.sh standby1_write.pg >> standby1_write.log'))
        standby1_tpcc.setDaemon(True)
        standby1_tpcc.start()
        status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/standby1_write.log")
        self.assertNotIn('socket is not closed', status, '新主节点125断开TPCC连接')

        time.sleep(20)

        step7 = '======step7:tpcc业务结束,查询集群状态;expect:集群状态正常======'
        self.logger.info(step7)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + step7)
        self.assertIn('S Primary Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + step5)
        self.assertIn('P Standby Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + step5)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[2].split('6003')[-1],
                      '执行失败' + step5)

    def tearDown(self):
        step8 = "======step8:环境清理,恢复参数;expect:环境清理成功,恢复参数成功======"
        self.logger.info(step8)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.logger.info(status)
        stop_tpcc_cmd = "ps -ef | grep runBenchmark | grep -v grep | " \
                        + "awk '{{print $2}}' | xargs kill -9"
        stop_tpcc = Primary_ROOTSH.exec_cmd_under_root(stop_tpcc_cmd)
        result1 = Primary_SH.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.txnstatus_cache_size}={self.txnstatus_cache_size_default}')
        restart_res = Primary_SH.restart_db_cluster()
        show_txnstatus_cache_size = self.com.show_param(self.txnstatus_cache_size)
        self.assertEquals(show_txnstatus_cache_size, '131072', '执行失败' + step8)

        recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.logger.info(recovery)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                      '执行失败' + step8)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + step8)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + step8)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + step8)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[2].split('6003')[-1],
                      '执行失败' + step8)

        self.logger.info(f"-----{os.path.basename(__file__)} end-----")